package com.example;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.List;

/**
 * JVM内存监控工具类
 * 用于实时监控各个内存区域的使用情况
 */
public class MemoryMonitor {
    
    private static final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
    private static final List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans();
    
    /**
     * 打印当前内存使用情况
     */
    public static void printMemoryUsage() {
        System.out.println("=== 内存使用情况 ===");
        
        // 堆内存使用情况
        MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
        System.out.println("堆内存:");
        System.out.println("  已提交: " + formatBytes(heapUsage.getCommitted()));
        System.out.println("  已使用: " + formatBytes(heapUsage.getUsed()));
        System.out.println("  最大值: " + formatBytes(heapUsage.getMax()));
        System.out.println("  初始值: " + formatBytes(heapUsage.getInit()));
        
        // 非堆内存使用情况
        MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
        System.out.println("非堆内存:");
        System.out.println("  已提交: " + formatBytes(nonHeapUsage.getCommitted()));
        System.out.println("  已使用: " + formatBytes(nonHeapUsage.getUsed()));
        System.out.println("  最大值: " + formatBytes(nonHeapUsage.getMax()));
        System.out.println("  初始值: " + formatBytes(nonHeapUsage.getInit()));
        
        // 各个内存池使用情况
        System.out.println("内存池详情:");
        for (MemoryPoolMXBean pool : memoryPools) {
            MemoryUsage usage = pool.getUsage();
            if (usage != null) {
                System.out.println("  " + pool.getName() + ":");
                System.out.println("    已提交: " + formatBytes(usage.getCommitted()));
                System.out.println("    已使用: " + formatBytes(usage.getUsed()));
                System.out.println("    最大值: " + formatBytes(usage.getMax()));
                System.out.println("    初始值: " + formatBytes(usage.getInit()));
                
                // 如果是年轻代或老年代，计算使用率
                if (usage.getMax() > 0) {
                    double usagePercentage = (double) usage.getUsed() / usage.getMax() * 100;
                    System.out.println("    使用率: " + String.format("%.2f%%", usagePercentage));
                }
            }
        }
        
        System.out.println("==================\n");
    }
    
    /**
     * 格式化字节数
     */
    private static String formatBytes(long bytes) {
        if (bytes < 1024) {
            return bytes + " B";
        } else if (bytes < 1024 * 1024) {
            return String.format("%.2f KB", bytes / 1024.0);
        } else if (bytes < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", bytes / (1024.0 * 1024));
        } else {
            return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
        }
    }
    
    /**
     * 获取指定内存池的使用情况
     */
    public static MemoryUsage getMemoryPoolUsage(String poolName) {
        for (MemoryPoolMXBean pool : memoryPools) {
            if (pool.getName().contains(poolName)) {
                return pool.getUsage();
            }
        }
        return null;
    }
}